
/**
 * Array 转 tree
 * arrayToTree:{
 *          id: '主键属性',
 *          parent: '父id属性',
 *          leaf: '叶子属性',
 *          leafValue: '叶子值',
 *          当根节点只有一个时,是否返回数组
 *          returnArrayWhenOnRoot: false
 * }
 *  参数解释:
 * 
 *   假如服务端返回的数据结构:
 *   [
 *     {id: 1, text: '一年级', pid: null, leaf: 2},
 *     {id: 2, text: '张山', pid: 1, leaf: 1}
 *   ]
 *  例如: 当arrayToTree配置为 
 *     { 
 *      id: 'id',
 *      parent: 'pid',
 *      leaf: 'leaf', 
 *      leafValue: '1' ,
 *      returnArrayWhenOnRoot: true
 *     }
 *    
 *   生成的数据格式为:
 *     [
 *      {
 *       id: 1,
 *       text: '一年级',
 *       leaf: false,
 *       children: [
 *         { id: 2, text: '张山', leaf: true }
 *       ]
 *      }
 *     ]
 *   
 *    如果需要对以上数据字段转换，可以在dataSrouce第三个参数中配置fieldMap
 * 
 * @author xiufu.wang
 */

function arrayToTree(arrayDatas, { arrayToTree }, dataSource) {
    const { id, parent, leaf, leafValue, returnArrayWhenOnRoot } = arrayToTree
    const res = {}
    const resArray = []
    arrayDatas = arrayDatas || []
    arrayDatas.forEach(r => {
        const _id = r[id]
        const _parent = r[parent]
        let nodeData = res[_id]  || (res[_id] = {})
        
        if (_parent){
            let parentNodeData = res[_parent]  || (res[_parent] = {children: []})
            if (!('children' in parentNodeData)){
                parentNodeData.children = []
            }
            parentNodeData.children.push(nodeData)
        }

        Object.assign(nodeData, {
            ...r,
            ...( !!(leaf) ? {leaf: (r[leaf] === leafValue) } : {} )
        })
        
        if (!_parent){
            resArray.push(nodeData)
        }
    });
    if (!leaf){
        Object.keys(res).forEach((r) => {
            res[r].leaf = (!res[r].children || res[r].children.length === 0)
        })
    }

    return returnArrayWhenOnRoot === false && resArray.length === 1 ? resArray[0] : resArray
}
export default function (datas, opt, dataSource) {
    if (opt.arrayToTree) {
        return arrayToTree(datas, opt, dataSource)
    }
    return datas
}